<template>
  <div class="environment-monitor">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2>设备环境监控</h2>
      <div class="header-actions">
        <el-button type="primary" icon="el-icon-refresh" @click="refreshData">刷新数据</el-button>
      </div>
    </div>

    <!-- 参数配置弹窗：编辑详情，两列表单布局 -->
    <el-dialog
      class="param-dialog"
      title="编辑详情"
      :visible.sync="paramDialogVisible"
      width="720px"
      @close="handleParamCancel">
      <el-form :model="paramForm" label-position="top">
        <!-- 第一行：设备类型（不可编辑）、所属库房*（不可编辑） -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="设备类型">
              <el-select v-model="paramForm.deviceType" disabled placeholder="选择设备类型">
                <el-option v-for="opt in paramOptions.deviceTypes" :key="opt.value" :label="opt.label" :value="opt.value"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="所属库房" required>
              <el-select v-model="paramForm.room" disabled placeholder="选择库房">
                <el-option v-for="opt in paramOptions.rooms" :key="opt.value" :label="opt.label" :value="opt.value"/>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 第二行：设备名称*，设备编号*（不可编辑） -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="设备名称" required>
              <el-input v-model="paramForm.deviceName" placeholder="请输入设备名称"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="设备编号" required>
              <el-select v-model="paramForm.deviceNumber" disabled placeholder="选择设备编号">
                <el-option v-for="opt in paramOptions.deviceNumbers" :key="opt.value" :label="opt.label" :value="opt.value"/>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 第三行：温度阈值、湿度阈值（两个输入框，中间连接符） -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="温度阈值">
              <div class="range-inputs">
                <el-input v-model="paramForm.tempMin" placeholder="20" style="width: 40%"/>
                <span class="range-dash">-</span>
                <el-input v-model="paramForm.tempMax" placeholder="100" style="width: 40%"/>
              </div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="湿度阈值">
              <div class="range-inputs">
                <el-input v-model="paramForm.humMin" placeholder="0" style="width: 40%"/>
                <span class="range-dash">-</span>
                <el-input v-model="paramForm.humMax" placeholder="100" style="width: 40%"/>
              </div>
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 第四行：温度系数、湿度系数 -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="温度系数">
              <el-input v-model="paramForm.tempCoeff" placeholder="0"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="湿度系数">
              <el-input v-model="paramForm.humCoeff" placeholder="0"/>
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 第五行：关联传感器、单选按钮组（本设备修改/批量修改） -->
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="关联传感器">
              <el-select v-model="paramForm.sensor" placeholder="请选择传感器">
                <el-option v-for="opt in paramOptions.sensors" :key="opt.value" :label="opt.label" :value="opt.value"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="修改范围">
              <el-radio-group v-model="paramForm.modifyScope">
                <el-radio label="self">本设备修改</el-radio>
                <el-radio label="batch">批量修改</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <!-- 弹窗底部按钮：取消与确认（确认为蓝色突出） -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleParamCancel">取消</el-button>
        <el-button type="primary" @click="handleParamConfirm">确认</el-button>
      </span>
    </el-dialog>

    <!-- 田字形布局的4个模块 -->
    <div class="monitor-grid">
      <!-- 第一个模块：参数设置 -->
      <div class="grid-item parameter-settings">
        <!-- 顶部区域：左侧设备与状态，右侧参数配置按钮 -->
        <div class="module-header">
          <div class="module-left">
            <!-- 顶部：设备名称与红色离线文字（在线为绿色） -->
            <span class="device-title">变送器</span>
            <span class="status-text" :class="deviceStatus.online ? 'online' : 'offline'">
              {{ deviceStatus.online ? '在线' : '离线' }}
            </span>
          </div>
          <div class="header-controls">
            <el-button type="primary" size="mini" @click="openParameterConfig">参数配置</el-button>
          </div>
        </div>

        <div class="module-content">
          <!-- 中间区域：控制器下拉选择框 -->
          <div class="module-middle" v-loading="devicesLoading">
            <!-- 中间：下拉选择框（尺寸与示例一致） -->
            <el-select v-model="selectedController" placeholder="区域控制器 - 温湿度变送..." size="mini" style="width: 100%;" @change="handleControllerChange">
              <el-option
                v-for="opt in controllerOptions"
                :key="opt.value"
                :label="opt.label"
                :value="opt.value"
              />
            </el-select>
          </div>

          <!-- 内容区域：温湿度阈值信息卡片 -->
          <div class="threshold-cards">
            <!-- 温度卡片：绿色温度计图标与范围 -->
            <div class="threshold-card temperature">
              <!-- 温度：绿色温度计图标，浅色卡片背景 -->
              <i class="el-icon-thermometer icon"></i>
              <div class="card-content">
                <div class="card-value">{{ getTempRangeText() }}</div>
                <div class="card-desc">温度阈值</div>
              </div>
            </div>

            <!-- 湿度卡片：蓝色湿度图标与范围 -->
            <div class="threshold-card humidity">
              <!-- 湿度：蓝色湿度图标（与示例一致使用 cloudy），浅色卡片背景 -->
              <i class="el-icon-cloudy icon"></i>
              <div class="card-content">
                <div class="card-value">{{ getHumRangeText() }}</div>
                <div class="card-desc">湿度阈值</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 第二个模块：设备状态 -->
      <div class="grid-item device-status">
        <div class="module-header">
          <i class="el-icon-monitor"></i>
          <span>设备状态</span>
        </div>
        <div class="module-content">
          <div class="status-cards">
            <!-- 温度状态 -->
            <div class="status-card">
              <div class="progress-circle">
                <svg class="progress" width="160" height="160" viewBox="0 0 160 160">
                  <!-- 背景圆环 -->
                  <circle
                    class="progress-background"
                    cx="80"
                    cy="80"
                    r="70"
                    stroke-width="10"
                    fill="none"
                  />
                  <!-- 进度圆环 -->
                  <circle
                    class="progress-bar temperature"
                    cx="80"
                    cy="80"
                    r="70"
                    stroke-width="10"
                    fill="none"
                    :stroke-dasharray="getProgressCircumference()"
                    :stroke-dashoffset="getTemperatureProgress()"
                    transform="rotate(-90 80 80)"
                  />
                </svg>
                <div class="progress-content">
                  <div class="value">{{ deviceStatus.temperature }}°C</div>
                  <div class="label">温度</div>
                </div>
              </div>
              <div class="card-time">{{ deviceStatus.updateTime }}</div>
            </div>

            <!-- 湿度状态 -->
            <div class="status-card">
              <div class="progress-circle">
                <svg class="progress" width="160" height="160" viewBox="0 0 160 160">
                  <!-- 背景圆环 -->
                  <circle
                    class="progress-background"
                    cx="80"
                    cy="80"
                    r="70"
                    stroke-width="10"
                    fill="none"
                  />
                  <!-- 进度圆环 -->
                  <circle
                    class="progress-bar humidity"
                    cx="80"
                    cy="80"
                    r="70"
                    stroke-width="10"
                    fill="none"
                    :stroke-dasharray="getProgressCircumference()"
                    :stroke-dashoffset="getHumidityProgress()"
                    transform="rotate(-90 80 80)"
                  />
                </svg>
                <div class="progress-content">
                  <div class="value">{{ deviceStatus.humidity }}%RH</div>
                  <div class="label">湿度</div>
                </div>
              </div>
              <div class="card-time">{{ deviceStatus.updateTime }}</div>
            </div>
          </div>

          <div class="device-info">
            <el-row :gutter="20">
              <el-col :span="12">
                <div class="info-item">
                  <span class="info-label">设备ID:</span>
                  <span class="info-value">{{ deviceStatus.deviceId }}</span>
                </div>
              </el-col>
              <el-col :span="12">
                <div class="info-item">
                  <span class="info-label">连接状态:</span>
                  <el-tag :type="deviceStatus.online ? 'success' : 'danger'" size="small">
                    {{ deviceStatus.online ? '在线' : '离线' }}
                  </el-tag>
                </div>
              </el-col>
            </el-row>
          </div>
        </div>
      </div>

      <!-- 第三个模块：温湿度曲线 -->
      <div class="grid-item chart-module">
        <div class="module-header">
          <i class="el-icon-data-line"></i>
          <span>温湿度曲线</span>
          <div class="header-controls">
            <el-select v-model="chartTimeRange" size="mini" @change="updateChart">
              <el-option label="最近1小时" value="1h"></el-option>
              <el-option label="最近6小时" value="6h"></el-option>
              <el-option label="最近24小时" value="24h"></el-option>
              <el-option label="最近7天" value="7d"></el-option>
            </el-select>
          </div>
        </div>
        <div class="module-content">
          <div id="temperatureHumidityChart" style="width: 100%; height: 300px;"></div>
        </div>
      </div>

      <!-- 第四个模块：运行日志 -->
      <div class="grid-item log-module">
        <div class="module-header">
          <i class="el-icon-document"></i>
          <span>运行日志</span>
          <div class="header-controls">
            <el-button type="text" size="mini" @click="clearLogs">清空日志</el-button>
          </div>
        </div>
        <div class="module-content">
          <div class="log-container" v-loading="logLoading">
            <div v-if="logs.length === 0 && !logLoading" class="no-data">
              暂无日志数据
            </div>
            <div v-for="(log, index) in logs" :key="index" class="log-item" :class="getLogClass(log.type)">
              <span class="log-time">{{ log.time }}</span>
              <el-tag :type="getLogTagType(log.type)" size="mini">{{ log.type }}</el-tag>
              <span class="log-device">{{ log.deviceName }}</span>
              <span class="log-message">{{ log.content }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import { getDeviceLogs, getDeviceStatus, getTemperatureHumidityData, saveParameters, getParameters, getTemperatureHumidityChart, updateTransmitterDevice, listTransmitterDevices } from '@/api/archives/environment'

export default {
  name: "EnvironmentMonitor",
  data() {
    return {
      // 参数设置表单
      parameterForm: {
        tempMin: 18.0,
        tempMax: 28.0,
        humidityMin: 40.0,
        humidityMax: 65.0
      },
      // 设备状态数据
      deviceStatus: {
        temperature: 0,
        humidity: 0,
        deviceId: "未知",
        online: false,
        updateTime: "-"
      },
      parameterLoading: false,
      
      // 图表相关
      chart: null,
      chartTimeRange: '6h',
      chartData: {
        times: [],
        temperatures: [],
        humidities: []
      },
      // 控制器选择与设备列表（接口加载）
      selectedController: '',
      controllerOptions: [],
      deviceList: [],
      selectedDevice: null,
      devicesLoading: false,
      
      // 日志数据
      logs: [],
      logLoading: false,
      
      // 定时器
      dataTimer: null,

      // 参数配置弹窗控制
      paramDialogVisible: false,
      // 参数配置表单模型（默认值）
      paramForm: {
        deviceType: '变送器',
        room: 'A 库房',
        deviceName: '温湿度变送器_1',
        deviceNumber: '01',
        tempMin: 20,
        tempMax: 100,
        humMin: 0,
        humMax: 100,
        tempCoeff: 0,
        humCoeff: 0,
        sensor: '自身传感器',
        modifyScope: 'self'
      },
      // 参数配置下拉选项（示例）
      paramOptions: {
        deviceTypes: [{ label: '变送器', value: '变送器' }],
        rooms: [{ label: 'A 库房', value: 'A 库房' }],
        deviceNumbers: [{ label: '01', value: '01' }],
        sensors: [
          { label: '自身传感器', value: '自身传感器' },
          { label: '外接传感器', value: '外接传感器' }
        ]
      }
    }
  },
  mounted() {
    this.initChart()
    this.loadData()
    // 定时刷新数据
    this.timer = setInterval(() => {
      this.loadData()
    }, 30000) // 30秒刷新一次
  },
  beforeDestroy() {
    if (this.timer) {
      clearInterval(this.timer)
    }
    if (this.chart) {
      this.chart.dispose()
    }
  },
  methods: {
    // 获取圆环周长
    getProgressCircumference() {
      const radius = 70;
      return 2 * Math.PI * radius;
    },

    // 计算温度进度
    getTemperatureProgress() {
      const circumference = this.getProgressCircumference();
      const maxTemp = 100; // 最大温度值
      const progress = (this.deviceStatus.temperature / maxTemp);
      return circumference * (1 - progress);
    },

    // 计算湿度进度
    getHumidityProgress() {
      const circumference = this.getProgressCircumference();
      const progress = (this.deviceStatus.humidity / 100);
      return circumference * (1 - progress);
    },

    // 打开参数配置对话或入口（示例交互）
    openParameterConfig() {
      // 打开参数配置弹窗，填充当前选中设备数据
      if (this.selectedDevice) {
        this.fillParamFormFromDevice(this.selectedDevice)
      }
      this.paramDialogVisible = true
    },

    // 下拉选择变更处理（示例交互）
    handleControllerChange(value) {
      const found = this.deviceList.find(d => String(d.id) === String(value))
      if (found) {
        this.selectedDevice = found
        this.deviceStatus.online = String(found.opStatus) === '1'
        this.fillParamFormFromDevice(found)
        // 切换设备后刷新温湿度曲线
        this.loadChartData()
        // 切换设备后刷新运行日志
        this.loadDeviceLogs()
      }
    },

    // 用设备数据填充弹窗表单
    fillParamFormFromDevice(device) {
      this.paramForm.deviceType = device.deviceType || '变送器'
      this.paramForm.room = device.storeName || 'A 库房'
      this.paramForm.deviceName = device.deviceName || '温湿度变送器_1'
      this.paramForm.deviceNumber = device.deviceAddrCode || '01'
      this.paramForm.tempMin = Number(device.temAlarmDown || 20)
      this.paramForm.tempMax = Number(device.temAlarmUp || 100)
      this.paramForm.humMin = Number(device.humAlarmDown || 0)
      this.paramForm.humMax = Number(device.humAlarmUp || 100)
      this.paramForm.tempCoeff = Number(device.temAdjust || 0)
      this.paramForm.humCoeff = Number(device.humAdjust || 0)
      this.paramForm.sensor = device.refSensorNo === '0000' ? '自身传感器' : '外接传感器'
      this.paramForm.modifyScope = 'self'
    },

    // 取消弹窗
    handleParamCancel() {
      this.paramDialogVisible = false
    },

    // 确认提交（示例）
    async handleParamConfirm() {
      // 简单校验必填项
      if (!this.paramForm.room || !this.paramForm.deviceName || !this.paramForm.deviceNumber) {
        this.$message({ type: 'warning', message: '请填写必填项' })
        return
      }
      // 组装后端需要的请求体（按需求字段映射）
      const payload = {
        deviceTypeCode: '01',
        storeId: 1,
        deviceName: this.paramForm.deviceName,
        deviceAddrCode: this.paramForm.deviceNumber,
        temAlarmDown: String(this.paramForm.tempMin),
        temAlarmUp: String(this.paramForm.tempMax),
        humAlarmDown: String(this.paramForm.humMin),
        humAlarmUp: String(this.paramForm.humMax),
        temAdjust: String(this.paramForm.tempCoeff),
        humAdjust: String(this.paramForm.humCoeff),
        // 关联传感器：根据选择映射，默认“自身传感器”-> 0000
        refSensorNo: this.paramForm.sensor === '自身传感器' ? '0000' : '0001',
        // 修改范围：本设备修改=0，批量修改=1
        modStatus: this.paramForm.modifyScope === 'self' ? 0 : 1,
        termId: 1,
        deviceType: this.paramForm.deviceType
      }

      try {
        // 调用后端接口：优先使用当前选中设备ID，若无则回退 13
        const idToUpdate = this.selectedDevice?.id || 13
        await updateTransmitterDevice(idToUpdate, payload)
        this.$message({ type: 'success', message: '参数配置已保存并提交后端' })
        this.paramDialogVisible = false
      } catch (e) {
        this.$message({ type: 'error', message: '提交失败，请稍后重试' })
      }
    },

    // 阈值卡片文本（基于当前选中设备）
    getTempRangeText() {
      const d = this.selectedDevice
      if (!d) return '—'
      return `${d.temAlarmDown || 20}-${d.temAlarmUp || 100}℃`
    },
    getHumRangeText() {
      const d = this.selectedDevice
      if (!d) return '—'
      return `${d.humAlarmDown || 0}-${d.humAlarmUp || 100}% RH`
    },

    // 加载所有数据
    async loadData() {
      await Promise.all([
        this.loadDeviceLogs(),
        this.loadDeviceStatus(),
        this.loadParameters(),
        this.loadChartData(), // 添加图表数据加载
        this.loadDeviceManageList() // 加载设备管理列表
      ])
    },
    // 加载设备管理列表（用于下拉与页面联动）
    async loadDeviceManageList() {
      try {
        this.devicesLoading = true
        const resp = await listTransmitterDevices()
        const ok = resp && (resp.code === 200 || resp.code === '200' || resp.code == 200)
        const arr = ok && Array.isArray(resp.data) ? resp.data : []
        this.deviceList = arr
        // 统一使用字符串类型的 value，避免 label 不显示 alias 的类型不匹配问题
        this.controllerOptions = arr.map(item => ({ label: item.alias || `设备-${item.id}`, value: String(item.id) }))
        if (arr.length > 0) {
          this.selectedController = String(arr[0].id)
          this.selectedDevice = arr[0]
          this.deviceStatus.online = String(arr[0].opStatus) === '1'
          this.fillParamFormFromDevice(arr[0])
          this.loadChartData()
          // 初始化默认设备的运行日志
          this.loadDeviceLogs()
        }
      } catch (e) {
        this.$message({ type: 'warning', message: '设备列表加载失败' })
        this.deviceList = []
        this.controllerOptions = []
      } finally {
        this.devicesLoading = false
      }
    },
    // 加载设备运行日志
    async loadDeviceLogs() {
      try {
        this.logLoading = true
        // 组装 POST 参数：与曲线接口一致，从当前选中设备获取
        const dev = this.selectedDevice || {}
        const payload = {
          storeId: dev.storeId != null ? dev.storeId : 1,
          deviceTypeCode: dev.deviceTypeCode || '01',
          deviceAddrCode: dev.deviceAddrCode || '01',
          termId: dev.termId != null ? dev.termId : 1,
          storeCode: dev.storeCode || 'storeCode'
        }
        const response = await getDeviceLogs(payload)
        console.log('=== API响应详细信息 ===')
        console.log('完整响应:', response)
        console.log('响应类型:', typeof response)
        console.log('code值:', response?.code, '类型:', typeof response?.code)
        console.log('data值:', response?.data, '是否为数组:', Array.isArray(response?.data))
        
        // 检查响应数据结构 - 修复code类型判断，支持字符串和数字类型的200
        if (response && (response.code === '200' || response.code === 200 || response.code == 200) && response.data && Array.isArray(response.data)) {
          console.log('=== 开始处理API数据 ===')
          console.log('原始数据条数:', response.data.length)
          
          this.logs = response.data.map((item, index) => {
            console.log(`处理第${index + 1}条数据:`, item)
            const processedItem = {
              time: item.createTime || '未知时间',
              type: this.getLogTypeText(item.logType),
              content: item.deviceOpLog || '无日志内容',
              deviceName: item.deviceName || '未知设备',
              status: item.status || '未知状态'
            }
            console.log(`处理后第${index + 1}条数据:`, processedItem)
            return processedItem
          })
          console.log('=== 最终处理结果 ===')
          console.log('处理后的日志数据:', this.logs)
          console.log('日志条数:', this.logs.length)
          
          // 显示成功消息
          this.$message({
            message: `成功加载 ${this.logs.length} 条运行日志`,
            type: 'success',
            duration: 2000
          })
        } else {
          // 如果API返回格式不符合预期，使用模拟数据
          console.warn('=== API返回数据格式异常 ===')
          console.warn('响应对象:', response)
          console.warn('code检查结果:', response?.code === '200', response?.code === 200, response?.code == 200)
          console.warn('data检查结果:', response?.data, Array.isArray(response?.data))
          
          this.logs = [
            {
              time: '2024-01-15 14:30:25',
              type: '信息',
              content: '设备连接正常',
              deviceName: '温湿度传感器01',
              status: '正常'
            },
            {
              time: '2024-01-15 14:25:10',
              type: '警告',
              content: '温度超出阈值',
              deviceName: '温湿度传感器01',
              status: '警告'
            }
          ]
        }
      } catch (error) {
        console.error('=== API请求失败 ===')
        console.error('错误详情:', error)
        console.error('错误类型:', error.constructor.name)
        console.error('错误消息:', error.message)
        
        // 检查是否是axios响应拦截器返回的错误
        if (error === 'error' || (typeof error === 'string' && error.includes('error'))) {
          console.warn('=== 可能是响应拦截器问题，尝试直接处理原始响应 ===')
          // 这种情况下，实际API可能是成功的，但被拦截器处理成了错误
          this.$message({
            message: '数据格式问题，请检查后端返回的code字段类型',
            type: 'warning',
            duration: 3000
          })
        }
        
        // 发生错误时使用模拟数据，避免页面崩溃
        this.logs = [
          {
            time: '2025-05-21 09:19:07',
            type: '警告',
            content: '温湿度变送器,温度异常（模拟数据）',
            deviceName: '温湿度变送器',
            status: '异常'
          },
          {
            time: '2025-05-21 09:15:30',
            type: '信息',
            content: '设备连接正常（模拟数据）',
            deviceName: '温湿度变送器',
            status: '正常'
          },
          {
            time: '2025-05-21 09:10:15',
            type: '错误',
            content: '传感器读取失败（模拟数据）',
            deviceName: '温湿度变送器',
            status: '错误'
          }
        ]
        console.log('=== 使用模拟数据 ===')
        console.log('模拟日志数据:', this.logs)
        
        // 显示友好的错误提示，但不阻止页面正常显示
        this.$message({
          message: '后端服务未启动，当前显示模拟数据',
          type: 'warning',
          duration: 3000
        })
      } finally {
        this.logLoading = false
      }
    },
    // 获取日志类型文本
    getLogTypeText(logType) {
      const typeMap = {
        '1': '警告',
        '2': '错误',
        '3': '信息'
      }
      return typeMap[logType] || '信息'
    },
    // 加载设备状态
    async loadDeviceStatus() {
      try {
        // 这里可以根据实际需要传入设备ID
        // const response = await getDeviceStatus(1)
        // 暂时使用模拟数据
      } catch (error) {
        console.error('加载设备状态失败:', error)
      }
    },
    // 加载参数设置
    async loadParameters() {
      try {
        // const response = await getParameters()
        // 暂时使用默认参数
      } catch (error) {
        console.error('加载参数设置失败:', error)
      }
    },
    // 初始化图表
    initChart() {
      this.chart = echarts.init(document.getElementById('temperatureHumidityChart'))
      
      const option = {
        title: {
          text: '温湿度趋势',
          textStyle: {
            fontSize: 14,
            color: '#333'
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          }
        },
        legend: {
          data: ['温度', '湿度'],
          bottom: 10
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '15%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: this.chartData.times
        },
        yAxis: [
          {
            type: 'value',
            name: '温度(°C)',
            position: 'left',
            axisLabel: {
              formatter: '{value}°C'
            }
          },
          {
            type: 'value',
            name: '湿度(%)',
            position: 'right',
            axisLabel: {
              formatter: '{value}%'
            }
          }
        ],
        series: [
          {
            name: '温度',
            type: 'line',
            yAxisIndex: 0,
            data: this.chartData.temperatures,
            smooth: true,
            itemStyle: {
              color: '#ff6b6b'
            }
          },
          {
            name: '湿度',
            type: 'line',
            yAxisIndex: 1,
            data: this.chartData.humidities,
            smooth: true,
            itemStyle: {
              color: '#4ecdc4'
            }
          }
        ]
      }
      
      this.chart.setOption(option)
    },
    
    // 更新图表
    updateChart() {
      // 这里应该调用后端接口获取不同时间范围的数据
      this.loadChartData()
    },
    
    // 加载图表数据
    async loadChartData() {
      try {
        console.log('=== 开始加载温湿度曲线数据 ===')
        // 组装 POST 参数：从当前选中设备获取必要字段
        const dev = this.selectedDevice || {}
        const payload = {
          // storeId：库房ID
          storeId: dev.storeId != null ? dev.storeId : 1,
          // 设备类型代码，如 '01'
          deviceTypeCode: dev.deviceTypeCode || '01',
          // 设备编号代码，如 '01'
          deviceAddrCode: dev.deviceAddrCode || '01',
          // 终端ID
          termId: dev.termId != null ? dev.termId : 1,
          // 库房编码
          storeCode: dev.storeCode || 'storeCode'
        }
        console.log('曲线查询参数:', payload)
        const response = await getTemperatureHumidityChart(payload)
        
        console.log('=== 温湿度曲线API响应 ===')
        console.log('完整响应:', response)
        console.log('响应类型:', typeof response)
        console.log('code值:', response?.code, '类型:', typeof response?.code)
        console.log('data值:', response?.data, '是否为数组:', Array.isArray(response?.data))
        
        // 检查响应数据结构 - 支持字符串和数字类型的200
        if (response && (response.code === '200' || response.code === 200 || response.code == 200) && response.data && Array.isArray(response.data)) {
          console.log('=== 开始处理温湿度曲线数据 ===')
          console.log('原始数据条数:', response.data.length)
          
          const times = []
          const temperatures = []
          const humidities = []
          
          response.data.forEach((item, index) => {
            console.log(`处理第${index + 1}条曲线数据:`, item)
            times.push(item.time || '未知时间')
            temperatures.push(parseFloat(item.tem) || 0)
            humidities.push(parseFloat(item.hum) || 0)
          })
          
          this.chartData = { times, temperatures, humidities }
          
          console.log('=== 处理后的图表数据 ===')
          console.log('时间轴:', times)
          console.log('温度数据:', temperatures)
          console.log('湿度数据:', humidities)
          
          // 更新图表
          if (this.chart) {
            this.chart.setOption({
              xAxis: {
                data: times
              },
              series: [
                { data: temperatures },
                { data: humidities }
              ]
            })
          }
          
          this.$message({
            message: `成功加载 ${response.data.length} 个数据点的温湿度曲线`,
            type: 'success',
            duration: 2000
          })
        } else {
          // 如果API返回格式不符合预期，使用模拟数据
          console.warn('=== 温湿度曲线API返回数据格式异常，使用模拟数据 ===')
          console.warn('响应对象:', response)
          
          this.generateMockChartData()
          
          this.$message({
            message: '温湿度曲线数据格式异常，显示模拟数据',
            type: 'warning',
            duration: 3000
          })
        }
      } catch (error) {
        console.error('=== 温湿度曲线API请求失败 ===')
        console.error('错误详情:', error)
        console.error('错误类型:', error.constructor.name)
        console.error('错误消息:', error.message)
        
        // 检查是否是axios响应拦截器返回的错误
        if (error === 'error' || (typeof error === 'string' && error.includes('error'))) {
          console.warn('=== 可能是响应拦截器问题，使用模拟数据 ===')
          this.$message({
            message: '温湿度曲线数据格式问题，请检查后端返回的code字段类型',
            type: 'warning',
            duration: 3000
          })
        } else {
          this.$message({
            message: '加载温湿度曲线失败，显示模拟数据',
            type: 'error',
            duration: 3000
          })
        }
        
        // 发生错误时使用模拟数据
        this.generateMockChartData()
      }
    },
    
    // 生成模拟图表数据
    generateMockChartData() {
      const now = new Date()
      const times = []
      const temperatures = []
      const humidities = []
      
      // 根据时间范围生成不同数量的数据点
      let dataPoints = 24 // 默认24小时
      let interval = 60 * 60 * 1000 // 1小时间隔
      
      switch (this.chartTimeRange) {
        case '1h':
          dataPoints = 12
          interval = 5 * 60 * 1000 // 5分钟间隔
          break
        case '6h':
          dataPoints = 12
          interval = 30 * 60 * 1000 // 30分钟间隔
          break
        case '24h':
          dataPoints = 24
          interval = 60 * 60 * 1000 // 1小时间隔
          break
        case '7d':
          dataPoints = 7
          interval = 24 * 60 * 60 * 1000 // 1天间隔
          break
      }
      
      for (let i = dataPoints - 1; i >= 0; i--) {
        const time = new Date(now.getTime() - i * interval)
        let timeLabel = ''
        
        if (this.chartTimeRange === '1h' || this.chartTimeRange === '6h') {
          timeLabel = time.getHours().toString().padStart(2, '0') + ':' + time.getMinutes().toString().padStart(2, '0')
        } else if (this.chartTimeRange === '24h') {
          timeLabel = time.getHours().toString().padStart(2, '0') + ':00'
        } else {
          timeLabel = (time.getMonth() + 1) + '/' + time.getDate()
        }
        
        times.push(timeLabel)
        temperatures.push((Math.random() * 10 + 20).toFixed(1))
        humidities.push((Math.random() * 30 + 40).toFixed(1))
      }
      
      this.chartData = { times, temperatures, humidities }
      
      if (this.chart) {
        this.chart.setOption({
          xAxis: {
            data: times
          },
          series: [
            { data: temperatures },
            { data: humidities }
          ]
        })
      }
    },
    
    // 获取温度状态样式
    getTemperatureStatus() {
      const temp = parseFloat(this.deviceStatus.temperature)
      if (temp < this.parameterForm.tempMin || temp > this.parameterForm.tempMax) {
        return 'status-warning'
      }
      return 'status-normal'
    },
    
    // 获取湿度状态样式
    getHumidityStatus() {
      const humidity = parseFloat(this.deviceStatus.humidity)
      if (humidity < this.parameterForm.humidityMin || humidity > this.parameterForm.humidityMax) {
        return 'status-warning'
      }
      return 'status-normal'
    },
    
    // 保存参数设置
    saveParameters() {
      this.parameterLoading = true
      // 这里应该调用后端接口保存参数
      setTimeout(() => {
        this.parameterLoading = false
        this.$modal.msgSuccess('参数设置保存成功')
        this.addLog('info', '参数设置已更新')
      }, 1000)
    },
    
    // 清空日志
    async clearLogs() {
      try {
        await this.$confirm('确认清空所有运行日志？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        // 调用清空日志API
        // await clearDeviceLogs()
        this.logs = []
        this.$message.success('日志已清空')
      } catch (error) {
        if (error !== 'cancel') {
          this.$message.error('清空日志失败')
        }
      }
    },
    
    // 获取日志样式类
    getLogClass(type) {
      const classMap = {
        '信息': 'log-info',
        '警告': 'log-warning',
        '错误': 'log-error'
      }
      return classMap[type] || 'log-info'
    },
    
    // 获取日志标签类型
    getLogTagType(type) {
      const typeMap = {
        '信息': 'info',
        '警告': 'warning',
        '错误': 'danger'
      }
      return typeMap[type] || 'info'
    },
    
    // 重置参数
    resetParameters() {
      this.parameterForm = {
        tempMin: 18.0,
        tempMax: 26.0,
        humidityMin: 40.0,
        humidityMax: 70.0
      }
    },
    
    // 刷新数据
    refreshData() {
      this.loadDeviceStatus()
      this.loadChartData()
      this.loadDeviceLogs()
      this.$message({
        message: '数据已刷新',
        type: 'success',
        duration: 2000
      })
    },
    
    // 加载设备状态
    loadDeviceStatus() {
      // 这里应该调用后端接口获取设备状态
      // 模拟数据更新
      this.deviceStatus.temperature = (Math.random() * 10 + 20).toFixed(1)
      this.deviceStatus.humidity = (Math.random() * 30 + 40).toFixed(1)
      this.deviceStatus.updateTime = new Date().toLocaleString()
    },
    
    // 开始数据轮询
    startDataPolling() {
      this.dataTimer = setInterval(() => {
        this.loadDeviceStatus()
      }, 30000) // 每30秒更新一次
    },
    
    // 加载初始数据
    loadInitialData() {
      this.loadDeviceStatus()
      this.loadChartData()
    },
    
    // 添加日志
    addLog(level, message) {
      const log = {
        time: new Date().toLocaleString(),
        level: level,
        message: message
      }
      this.logs.unshift(log)
      if (this.logs.length > 50) {
        this.logs = this.logs.slice(0, 50)
      }
    },
    
    // 清空日志
    clearLogs() {
      this.$confirm('确认清空所有日志记录？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.logs = []
        this.$modal.msgSuccess('日志已清空')
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.environment-monitor {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;

  .page-header {
    margin-bottom: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;

    h2 {
      margin: 0;
      font-size: 24px;
      color: #303133;
    }
  }

  .monitor-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-gap: 20px;

    .grid-item {
      background: #fff;
      border-radius: 8px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      transition: all 0.3s ease;

      &:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.15);
      }

      .module-header {
        padding: 15px 20px;
        border-bottom: 1px solid #ebeef5;
        display: flex;
        align-items: center;

        i {
          margin-right: 8px;
          font-size: 18px;
          color: #409EFF;
        }

        span {
          font-size: 16px;
          font-weight: 500;
          color: #303133;
        }

        .header-controls {
          margin-left: auto;
        }
      }

      .module-content {
        padding: 20px;
      }
    }

    .device-status {
      .status-cards {
        display: flex;
        justify-content: space-around;
        align-items: center;
        margin-bottom: 20px;
        padding: 20px 0;

        .status-card {
          text-align: center;
          
          .progress-circle {
            position: relative;
            display: inline-block;
            margin-bottom: 15px;
            
            .progress {
              transform: rotate(-90deg);
              filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
            }

            .progress-background {
              stroke: #e9ecef;
              stroke-linecap: round;
            }

            .progress-bar {
              transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1);
              stroke-linecap: round;
              
              &.temperature {
                stroke: #409eff;
                filter: drop-shadow(0 0 2px rgba(64, 158, 255, 0.5));
              }
              
              &.humidity {
                stroke: #67c23a;
                filter: drop-shadow(0 0 2px rgba(103, 194, 58, 0.5));
              }
            }

            .progress-content {
              position: absolute;
              top: 50%;
              left: 50%;
              transform: translate(-50%, -50%);
              text-align: center;
              transition: all 0.3s ease;

              .value {
                font-size: 28px;
                font-weight: bold;
                line-height: 1.2;
                background: linear-gradient(45deg, #303133, #606266);
                -webkit-background-clip: text;
                -webkit-text-fill-color: transparent;
                transition: all 0.3s ease;
              }

              .label {
                font-size: 14px;
                color: #909399;
                margin-top: 5px;
                opacity: 0.8;
                transition: all 0.3s ease;
              }
            }

            &:hover {
              .progress-content {
                transform: translate(-50%, -52%);

                .value {
                  transform: scale(1.05);
                }

                .label {
                  opacity: 1;
                }
              }
            }
          }

          .card-time {
            font-size: 12px;
            color: #909399;
            margin-top: 5px;
          }
        }
      }

      .device-info {
        background: #f5f7fa;
        border-radius: 6px;
        padding: 15px;
        margin-top: 10px;
        transition: all 0.3s ease;

        &:hover {
          background: #f0f2f5;
        }

        .info-item {
          display: flex;
          align-items: center;
          margin-bottom: 10px;
          
          &:last-child {
            margin-bottom: 0;
          }

          .info-label {
            color: #909399;
            margin-right: 10px;
            font-size: 14px;
            transition: color 0.3s ease;
          }

          .info-value {
            color: #303133;
            font-size: 14px;
            transition: all 0.3s ease;
          }

          :deep(.el-tag) {
            margin-left: 5px;
            transition: all 0.3s ease;

            &.el-tag--success {
              background-color: rgba(103, 194, 58, 0.1);
              border-color: rgba(103, 194, 58, 0.2);
              color: #67c23a;

              &:hover {
                background-color: rgba(103, 194, 58, 0.2);
              }
            }

            &.el-tag--danger {
              background-color: rgba(245, 108, 108, 0.1);
              border-color: rgba(245, 108, 108, 0.2);
              color: #f56c6c;

              &:hover {
                background-color: rgba(245, 108, 108, 0.2);
              }
            }
          }

          &:hover {
            .info-label {
              color: #606266;
            }

            .info-value {
              color: #303133;
              transform: translateX(2px);
            }
          }
        }
      }
    }

    // ... 其他模块的样式 ...
  }
}
</style>

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 0 10px;
}

.page-header h2 {
  margin: 0;
  color: #333;
  font-size: 24px;
}

.monitor-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 20px;
  height: calc(100vh - 160px);
}

.grid-item {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.module-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 15px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 500;
}

.module-header i {
  margin-right: 8px;
  font-size: 16px;
}

.header-controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

.module-content {
  flex: 1;
  padding: 20px;
  overflow: auto;
}

/* 参数设置模块样式 */
.parameter-settings .module-header {
  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}
/* 参数设置模块新增样式 */
.parameter-settings {
  .module-left {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .device-title {
    font-size: 16px;
    font-weight: 500;
  }

  /* 顶部状态文字：在线绿色，离线红色 */
  .status-text {
    font-size: 14px;
    font-weight: 500;
  }
  .status-text.online { color: #67c23a; }
  .status-text.offline { color: #f56c6c; }

  .module-middle {
    margin-bottom: 16px;
    /* 下拉选择框风格与示例一致 */
    :deep(.el-select) {
      width: 100%;
    }
    :deep(.el-select .el-input__inner) {
      height: 30px;
      border-radius: 6px;
      background: #f5f7fa;
      border-color: #dcdfe6;
    }
  }

  .threshold-cards {
    /* 阈值卡片布局：改为单列纵向，增加上下间距 */
    display: grid;
    grid-template-columns: 1fr; /* 单列长卡片 */
    row-gap: 16px; /* 卡片上下间隔 */
  }

  .threshold-card {
    display: flex;
    align-items: center;
    /* 浅色卡片背景与细边框（对齐示例） */
    background: #fff; /* 卡片浅色底 */
    border: 1px solid #ebeef5; /* 基础细边框 */
    border-radius: 12px; /* 更圆的角，增强卡片感 */
    padding: 18px 16px; /* 稍微增大内边距，让卡片更舒展 */
    min-height: 72px; /* 长卡片的视觉高度 */
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);

    .icon {
      font-size: 28px;
      margin-right: 12px;
    }

    .card-content {
      display: flex;
      flex-direction: column;
    }

    /* 文案排版：数值更醒目，说明为次要 */
    .card-value { font-size: 28px; font-weight: 700; color: #303133; }

    .card-desc { font-size: 14px; color: #909399; margin-top: 4px; }
  }

  .threshold-card.temperature {
    /* 温度卡片：浅绿色背景 + 更明确的绿色边框，圆角保持一致 */
    background: linear-gradient(180deg, rgba(103, 194, 58, 0.08), rgba(103, 194, 58, 0.03));
    border-color: rgba(103, 194, 58, 0.35);
    border-width: 1px;
    border-style: solid;
    .icon { color: #67c23a; }
  }

  .threshold-card.humidity {
    /* 湿度卡片：浅蓝色背景 + 更明确的蓝色边框，圆角保持一致 */
    background: linear-gradient(180deg, rgba(64, 158, 255, 0.08), rgba(64, 158, 255, 0.03));
    border-color: rgba(64, 158, 255, 0.35);
    border-width: 1px;
    border-style: solid;
    .icon { color: #409eff; }
  }

  /* 弹窗内范围输入样式与按钮区域 */
  :deep(.param-dialog .dialog-footer) {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
  }
  .range-inputs {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .range-dash {
    color: #909399;
  }
}

.input-label {
  font-size: 12px;
  color: #666;
  text-align: center;
  margin-top: 5px;
}

/* 设备状态模块样式 */
.device-status .module-header {
  background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
}

.status-cards {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
}

.status-card {
  flex: 1;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 8px;
  padding: 20px;
  color: white;
  display: flex;
  align-items: center;
}

.temperature-card {
  background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
}

.humidity-card {
  background: linear-gradient(135deg, #4ecdc4 0%, #44a08d 100%);
}

.card-icon {
  font-size: 32px;
  margin-right: 15px;
  opacity: 0.8;
}

.card-content {
  flex: 1;
}

.card-title {
  font-size: 14px;
  opacity: 0.9;
  margin-bottom: 5px;
}

.card-value {
  font-size: 28px;
  font-weight: bold;
  margin-bottom: 5px;
}

.card-time {
  font-size: 12px;
  opacity: 0.7;
}

.status-normal {
  color: #67c23a;
}

.status-warning {
  color: #e6a23c;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.7; }
  100% { opacity: 1; }
}

.device-info {
  background: #f8f9fa;
  border-radius: 6px;
  padding: 15px;
}

.info-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.info-item:last-child {
  margin-bottom: 0;
}

.info-label {
  font-weight: 500;
  color: #666;
  margin-right: 10px;
}

.info-value {
  color: #333;
}

/* 图表模块样式 */
.chart-module .module-header {
  background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
}

/* 日志模块样式 */
.log-module .module-header {
  background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
  color: #333;
}

.log-container {
  height: 100%;
  overflow-y: auto;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  background: #fafafa;
}

.log-item {
  display: flex;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
  font-size: 12px;
}

.log-item:last-child {
  border-bottom: none;
}

.log-time {
  color: #999;
  margin-right: 8px;
  min-width: 130px;
}

.log-device {
  color: #666;
  margin: 0 8px;
  min-width: 80px;
}

.log-message {
  flex: 1;
  color: #333;
}

.log-info {
  background-color: #f0f9ff;
}

.log-warning {
  background-color: #fffbf0;
}

.log-error {
  background-color: #fef0f0;
}

.no-data {
  text-align: center;
  color: #999;
  padding: 20px;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .monitor-grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto auto;
    height: auto;
  }
  
  .status-cards {
    flex-direction: column;
  }
}
</style>


